/**  
 * Copyright (c) 2010 University of Pennsylvania.
 *     All rights reserved.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an "AS
 *  IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 *  express or implied.  See the License for the specific language
 *  governing permissions and limitations under the License.
 *
 */
 
#define ADDRDOMAIN_BITS 8    // address domain
#define ADDR_BITS       8    // how many bits used internally, if less than domain - hashes

#if ADDR_BITS == 8
  #define ADDR_BITMASK 0xff
#elif ADDR_BITS == 12
  #define ADDR_BITMASK 0xfff
#else
  #define ADDR_BITS 0xffff
#endif

uint8_t marshal_checksize;   // if 1 will only find out size, and not marshall in buffer

void init_mmarshal();

void marshal_byte(uint8_t **pos, uint8_t byte);
uint8_t unmarshal_byte(uint8_t **pos);
void marshal_word(uint8_t **pos, uint16_t word);
uint16_t unmarshal_word(uint8_t **pos);
void marshal_long(uint8_t **pos, uint32_t l);
uint32_t unmarshal_long(uint8_t **pos);
void marshal_wordvb(uint8_t **pos, uint32_t word);
uint32_t unmarshal_wordvb(uint8_t **pos);
void marshal_buffer(uint8_t **pos, void *buf, uint8_t size);
void unmarshal_buffer(uint8_t **pos, void *buf, uint8_t size);
void marshal_summary(uint8_t **pos, SUMMARY *s);
void unmarshal_summary(uint8_t **pos, SUMMARY *s);
void marshal_addr(uint8_t **pos, ADDRESS addr);
ADDRESS unmarshal_addr(uint8_t **pos);
void marshal_addrs(uint8_t **pos, ADDRESS addr1, ADDRESS addr2);
void unmarshal_addrs(uint8_t **pos, ADDRESS *addr1, ADDRESS *addr2);
void marshal_pathvec(uint8_t **pos, ADDRESS *path, uint8_t len);
void unmarshal_pathvec(uint8_t **pos, ADDRESS *path, uint8_t len);
void marshal_pathlevels(uint8_t **pos, uint8_t *path_levels, uint8_t path_len);
void unmarshal_pathlevels(uint8_t **pos, uint8_t *path_levels, uint8_t path_len);

uint8_t marshal_discoverymsg(DISCOVERY_MSG *msg, uint8_t *buffer);
uint8_t unmarshal_discoverymsg(DISCOVERY_MSG *msg, uint8_t *buffer);
uint8_t marshal_treeconstructmsg(TREECONSTRUCT_MSG *msg, uint8_t *buffer);
uint8_t unmarshal_treeconstructmsg(TREECONSTRUCT_MSG *msg, uint8_t *buffer);
uint8_t marshal_treecommitmsg(TREECOMMIT_MSG *msg, uint8_t *buffer);
uint8_t unmarshal_treecommitmsg(TREECOMMIT_MSG *msg, uint8_t *buffer);
uint8_t marshal_treesummarymsg(TREESUMMARY_MSG *msg, uint8_t *buffer);
uint8_t unmarshal_treesummarymsg(TREESUMMARY_MSG *msg, uint8_t *buffer);
uint8_t marshal_treesummaryupdatemsg(TREESUMMARYUPDATE_MSG *msg, uint8_t *buffer);
uint8_t unmarshal_treesummaryupdatemsg(TREESUMMARYUPDATE_MSG *msg, uint8_t *buffer);
uint8_t marshal_treerootnotifymsg(TREEROOTNOTIFY_MSG *msg, uint8_t *buffer);
uint8_t unmarshal_treerootnotifymsg(TREEROOTNOTIFY_MSG *msg, uint8_t *buffer);

uint8_t marshal_routemsg(ROUTE_MSG *msg, uint8_t *buffer);
uint8_t marshalest_routemsg(ROUTE_MSG *msg);
uint8_t unmarshal_routemsg(ROUTE_MSG *msg, uint8_t *buffer);
uint8_t unmarshal_routemsg_head(ROUTE_MSG *msg, uint8_t *buffer);
uint8_t marshal_basefloodmsg(BASEFLOOD_MSG *msg, uint8_t *buffer);
uint8_t unmarshal_basefloodmsg(BASEFLOOD_MSG *msg, uint8_t *buffer);
uint8_t marshal_forwardmsg(FORWARD_MSG *msg, uint8_t *buffer);
uint8_t marshalest_forwardmsg(FORWARD_MSG *msg);
uint8_t unmarshal_forwardmsg(FORWARD_MSG *msg, uint8_t *buffer);
uint8_t unmarshal_forwardmsg_head(FORWARD_MSG *msg, uint8_t *buffer);
uint8_t marshal_forwardbufferexchangemsg(FORWARDBUFFEREXCHANGE_MSG *msg, uint8_t *buffer);
uint8_t unmarshal_forwardbufferexchangemsg(FORWARDBUFFEREXCHANGE_MSG *msg, uint8_t *buffer);
uint8_t marshal_pathsubscribemsg(PATHSUBSCRIBE_MSG *msg, uint8_t *buffer);
uint8_t marshalest_pathsubscribemsg(PATHSUBSCRIBE_MSG *msg);
uint8_t unmarshal_pathsubscribemsg(PATHSUBSCRIBE_MSG *msg, uint8_t *buffer);
uint8_t marshal_pathrespondmsg(PATHRESPOND_MSG *msg, uint8_t *buffer);
uint8_t unmarshal_pathrespondmsg(PATHRESPOND_MSG *msg, uint8_t *buffer);

uint8_t marshal_initmsghi(INIT_MSGHI *msg, uint8_t *buffer);
uint8_t unmarshal_initmsghi(INIT_MSGHI *msg, uint8_t *buffer);
uint8_t marshal_confirmjoinmsghi(CONFIRMJOIN_MSGHI *msg, uint8_t *buffer);
uint8_t unmarshal_confirmjoinmsghi(CONFIRMJOIN_MSGHI *msg, uint8_t *buffer);
uint8_t marshal_confirmsourcemsghi(CONFIRMSOURCE_MSGHI *msg, uint8_t *buffer);
uint8_t unmarshal_confirmsourcemsghi(CONFIRMSOURCE_MSGHI *msg, uint8_t *buffer);
uint8_t marshal_confirmtargetsourcemsghi(CONFIRMTARGETSOURCE_MSGHI *msg, uint8_t *buffer);
uint8_t unmarshal_confirmtargetsourcemsghi(CONFIRMTARGETSOURCE_MSGHI *msg, uint8_t *buffer);
uint8_t marshal_tuplemsghi(TUPLE_MSGHI *msg, uint8_t *buffer);
uint8_t marshalest_tuplemsghi(TUPLE_MSGHI *msg);
uint8_t unmarshal_tuplemsghi(TUPLE_MSGHI *msg, uint8_t *buffer, ADDRESS source_node);
uint8_t marshal_repairmsghi(REPAIR_MSGHI *msg, uint8_t *buffer);
uint8_t unmarshal_repairmsghi(REPAIR_MSGHI *msg, uint8_t *buffer);
uint8_t marshal_estupdatemsghi(ESTUPDATE_MSGHI *msg, uint8_t *buffer);
uint8_t unmarshal_estupdatemsghi(ESTUPDATE_MSGHI *msg, uint8_t *buffer);
uint8_t marshal_attrupdatemsghi(ATTRUPDATE_MSGHI *msg, uint8_t *buffer);
uint8_t unmarshal_attrupdatemsghi(ATTRUPDATE_MSGHI *msg, uint8_t *buffer);
void marshal_queryspec(uint8_t **pos, QUERYSPEC_ENTRY *spec);
void unmarshal_queryspec(uint8_t **pos, QUERYSPEC_ENTRY *spec);
uint8_t marshal_queryspecmsghi(QUERYSPEC_MSGHI *msg, uint8_t *buffer);
uint8_t marshal_queryspecpmsghi(QUERYSPECP_MSGHI *msg, uint8_t *buffer);
uint8_t marshalest_queryspecpmsghi(QUERYSPECP_MSGHI *msg);
uint8_t unmarshal_queryspecmsghi(QUERYSPEC_MSGHI *msg, uint8_t *buffer);
uint8_t unmarshal_queryspecpmsghi(QUERYSPECP_MSGHI *msg, uint8_t *buffer);
uint8_t marshal_summaryspecmsghi(SUMMARYSPEC_MSGHI *msg, uint8_t *buffer);
uint8_t unmarshal_summaryspecmsghi(SUMMARYSPEC_MSGHI *msg, uint8_t *buffer);
uint8_t marshal_pathcollapsemsghi(PATHCOLLAPSE_MSGHI *msg, uint8_t *buffer);
uint8_t marshalest_pathcollapsemsghi(PATHCOLLAPSE_MSGHI *msg);
uint8_t unmarshal_pathcollapsemsghi(PATHCOLLAPSE_MSGHI *msg, uint8_t *buffer, ADDRESS source_node);
uint8_t marshal_coordcostmsghi(COORDCOST_MSGHI *msg, uint8_t *buffer);
uint8_t marshalest_coordcostmsghi(COORDCOST_MSGHI *msg);
uint8_t unmarshal_coordcostmsghi(COORDCOST_MSGHI *msg, uint8_t *buffer);
uint8_t marshal_coorddecisionmsghi(COORDDECISION_MSGHI *msg, uint8_t *buffer);
uint8_t unmarshal_coorddecisionmsghi(COORDDECISION_MSGHI *msg, uint8_t *buffer);
uint8_t marshal_statsmsghi(STATS_MSGHI *msg, uint8_t *buffer);
uint8_t unmarshal_statsmsghi(STATS_MSGHI *msg, uint8_t *buffer);




